#include <iostream>
#include <cstring>

using namespace std;

const int N = int(1e5 + 10);

// nums数组表示当前树根的子节点数量, 包含树根
int p[N], nums[N]; 
int n;

void init(int n)
{
	for (int i = 1; i <= n; i++)
	{
		p[i] = i;
		nums[i] = 1;
	}
}

// 返回连通图编号
int find(int x)
{// 假设find返回树根, 那么链上的所有p[x]都指向树根, 递归中止在树根处
 // 想象时应该从递归结尾逐层向上递推出关系
	if (p[x] != x) p[x] = find(p[x]); 
	return p[x];
}

// 返回连通图节点数量
int sizes(int x)
{
	return nums[find(x)];
}

// 查询节点a与节点b是否在同一连通图
int query(int a, int b)
{
	return find(a) == find(b);
}

// 在节点a与b连接一条线
// 相当于合并两个连通图
void merge(int a, int b)
{
	int i = find(a);
	int j = find(b);
	if (i == j) return;
	nums[i] += nums[j];
	p[j] = i;
}

int main(void)
{
	int m, a, b;
	char mode[3];
	scanf("%d%d", &n, &m);

	init(n);

	while (m--)
	{
		scanf("%s%d", mode, &a);
		if (mode[0] == 'C')
		{
			scanf("%d", &b);
			merge(a, b);
		}
		else if (mode[1] == '1')
		{
			scanf("%d", &b);
			printf("%s\n", query(a, b) ? "Yes" : "No");
		}
		else if (mode[1] == '2')
			printf("%d\n", sizes(a));
	}

	return 0;
}